import { INVALID_VALUE, PRIORITY_VIEW } from "../../../Core/CoreDefine";
import GParam from "../../../Core/GEvent/GParam";
import GChild from "../../../Core/GView/GChild";
import { Res } from "../../Common/UIResources";
import GameMgr from "../../Logic/GameMgr";
import { JXEAniNames } from "../JXBattle/JXULDefine";
import { GCtrl } from './../../../Core/GCtrl';
import { CMsg, EQUIP_PART } from './../../Common/Define';

const { property, ccclass } = cc._decorator
@ccclass
export default class HeroChange extends GChild {
	@property(cc.Node) heroNode: cc.Node = null;
	private sk_hero: sp.Skeleton = null;
	private _heroId: number = null;
	private _heroData: IHeroData = null;

	public skillPostfix: boolean = false;
	public onGLoad() {
		GCtrl.ES.on(CMsg.client.equip.onEquipPutOff, this, this.onPutOffEquip.bind(this), PRIORITY_VIEW);
		GCtrl.ES.on(CMsg.client.equip.onEquipPutOn, this, this.onPutOnEquip.bind(this), PRIORITY_VIEW);
		let sk = this.heroNode.getComponent(sp.Skeleton);
		if (!sk) {
			sk = this.addComponent(sp.Skeleton);
		}
		this.sk_hero = sk;
	}

	public init(hero: number | IHeroData) {
		if (typeof (hero) === "number") {
			let heroId = hero
			if (!heroId || heroId == INVALID_VALUE) {
				this.node.active = false;
				this._heroId = null;
				return;
			}
			if (this._heroId == heroId) {
				return;
			}
			this._heroId = heroId;
		} else {
			if (hero) {
				this._heroData = hero;
				this._heroId = hero.tableId;
			} else {
				this.node.active = false;
				this._heroId = null;
				return;
			}
		}
		this.node.active = true;
		if ((this.sk_hero && !this.sk_hero.skeletonData) || typeof (hero) === "number") {
			let heroInfo = GameMgr.heroData.getRaw<SHeroDataRaw>(this._heroId);
			let path = Res.model + heroInfo.animation + "/" + heroInfo.animation;
			let self = this;
			this.assetImpl.spine(path, (data: sp.SkeletonData) => {
				self.sk_hero.skeletonData = data;
				self.sk_hero.setSkin("skin1");
				self.sk_hero.setAnimation(0, JXEAniNames.idle, true);
				this.initModelDefaul();
				this.initModelByEquip();
			})
		} else {
			this.initModelDefaul();
			this.initModelByEquip();
		}
	}

	/**
	 * 初始化模型通过默认数据
	 * @memberof HeroStand
	 */
	public initModelDefaul() {
		let equips: any[] = [];
		equips = this._heroData ? this._heroData.equips : GameMgr.RBagData.getOwnerAllEquip(this._heroId);
		if (this.sk_hero) {
			this.sk_hero.setSkin("skin1");
			this.sk_hero.setAnimation(0, JXEAniNames.idle, true);
		}
		if (equips.length > 0) {
			for (let i = 0; i < equips.length; i++) {
				let info = equips[i];
				if (!info || equips[i] == '-1') continue;
				if (typeof (info) === "number") {
					this.changeModuleBuId(info, false);
				} else {
					let jxEquip = GameMgr.RBagData.getEquipDataById(info)
					this.changeModuleBuId(jxEquip.itemData.id, false)
				}
			}
		} else {
			let heroInfo = GameMgr.heroData.getRaw<SHeroDataRaw>(this._heroId);
			if (heroInfo.slots && this.sk_hero) {
				for (let i = 0; i < heroInfo.slots.length; i++) {
					try {
						this.sk_hero.setAttachment(heroInfo.slots[i], heroInfo.defaultAttach[i]);
					} catch (error) {
						cc.error(error);
					}
				}
			}
		}
	}

	/**
	 * 初始化模型通过装备
	 * @return {*} 
	 * @memberof HeroStand
	 */
	public initModelByEquip() {
		if (!this.sk_hero) return;
		let heroData = this._heroData ? this._heroData : GameMgr.rHeroData.getHero(this._heroId);
		if (!heroData) return;
		let equips = heroData.equips as any[];
		for (let i = 0; i < equips.length; i++) {
			if (equips[i] == '-1' || equips[i] == null) {
				continue;
			}
			let jxEquip = null;
			if (typeof (equips[i]) === "number") {
				this.changeModuleBuId(equips[i] as number, true)
			} else {
				jxEquip = GameMgr.RBagData.getEquipDataById(equips[i]);
				this.changeModuleBuId(jxEquip.itemData.id, true)
			}

		}
	}

	/**
	 * 穿戴装备 
	 * @param {*} _
	 * @param {GParam} parm
	 * @return {*} 
	 * @memberof HeroStand
	 */
	public onPutOnEquip(_, parm: GParam) {
		let info = parm.get<EquipPutInfo>();
		if (info.heroId != this._heroId) return;
		let equipId = info.equipId;
		let raw = GameMgr.RBagData.getEquipDataById(equipId).itemData.raw as SEquipDataRaw;
		if (raw.seat === EQUIP_PART.CLOTHING) {
			this.initModelByEquip();
		} else {
			this.changeModuleBuId(raw.id, true)
		}

	}

	/**
	 * 卸装跟一键卸装
	 * @param {*} _
	 * @param {GParam} parm
	 * @return {*} 
	 * @memberof HeroStand
	 */
	public onPutOffEquip(_, parm: GParam) {
		let info = parm.get<EquipPutInfo>();
		if (info.heroId != this._heroId) return;
		let equipId = info.equipId;
		let raw = GameMgr.RBagData.getEquipDataById(equipId).itemData.raw as SEquipDataRaw;
		if (raw.seat === EQUIP_PART.CLOTHING) {
			this.initModelDefaul();
			this.initModelByEquip();
		} else {
			this.changeModuleBuId(raw.id, false)
		}

	}

	/**移除英雄 */
	public onDelHero(_, parm: GParam) {
		let heroId = parm.get();
		if (heroId == this._heroId) {
			this.init(null);
		}
	}

	/**
	 * 通过装备id改变英雄形象
	 * @protected
	 * @param {number} equipId
	 * @memberof HeroStand
	 */
	protected changeModuleBuId(equipId: number, show: boolean) {
		let equipInfo = GameMgr.equipData.getRaw<SEquipDataRaw>(equipId);
		if (equipInfo && equipInfo.skin) {
			if (show) {
				this.sk_hero.setSkin(equipInfo.skin[0]);
				this.skillPostfix = !!equipInfo.skin[1];
			} else {
				this.sk_hero.setSkin("skin1");
				this.skillPostfix = false;
			}
			this.sk_hero.setAnimation(0, JXEAniNames.idle, true);
		}
		if (equipInfo && equipInfo.slots) {
			for (let i = 0; i < equipInfo.slots.length; i++) {
				try {
					let attach = show ? equipInfo.showAttach[i] : equipInfo.hideAttach[i]
					if (!attach) {
						let slot = this.sk_hero.findSlot(equipInfo.slots[i]);
						slot.setAttachment(null);
					} else {
						this.sk_hero.setAttachment(equipInfo.slots[i], attach);
					}

				} catch (error) {
					console.error(error);
				}
			}
		}
	}
}